package com.hhc.decorator;

/**
 * 示例中，我们首先定义了抽象组件 Coffee 和具体组件 SimpleCoffee。
 * 然后，我们创建了抽象装饰者 CoffeeDecorator，它内部包含了一个指向抽象组件的引用。
 * 接下来，我们定义了具体装饰者 MilkDecorator 和 SugarDecorator，它们分别添加牛奶和糖的功能。
 */
// 1. 抽象组件
interface Coffee {
    String getDescription();
    double cost();
}

// 2. 具体组件
class SimpleCoffee implements Coffee {
    @Override
    public String getDescription() {
        return "Simple Coffee";
    }

    @Override
    public double cost() {
        return 2.0;
    }
}

// 3. 抽象装饰者
abstract class CoffeeDecorator implements Coffee {
    protected Coffee decoratedCoffee;

    public CoffeeDecorator(Coffee coffee) {
        this.decoratedCoffee = coffee;
    }

    @Override
    public String getDescription() {
        return decoratedCoffee.getDescription();
    }

    @Override
    public double cost() {
        return decoratedCoffee.cost();
    }
}

// 4. 具体装饰者
class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return super.getDescription() + ", with Milk";
    }

    @Override
    public double cost() {
        return super.cost() + 0.5; // Add the cost of milk
    }
}

class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return super.getDescription() + ", with Sugar";
    }

    @Override
    public double cost() {
        return super.cost() + 0.2; // Add the cost of sugar
    }
}

public class Main {
    public static void main(String[] args) {
        // 创建一个简单的咖啡
        Coffee coffee = new SimpleCoffee();
        System.out.println("Cost: " + coffee.cost() + ", Description: " + coffee.getDescription());

        // 使用装饰者来加牛奶和糖
        coffee = new MilkDecorator(coffee);
        coffee = new SugarDecorator(coffee);
        System.out.println("Cost: " + coffee.cost() + ", Description: " + coffee.getDescription());
    }
}